
import { useParams } from "react-router-dom";
import { useContext, useEffect, useState, useMemo, useCallback,useReducer } from "react";
import React from "react";
import {nanoid} from "nanoid"
import "./index.css";
import { BookListContext } from "../../App";

import ToolBar from "../../components/ToolBar";
import NoteBox from "../../components/NoteBox";
import NoteReadBox from "../../components/NoteReadBox";
import './index.css';
import ReaderControls from "../../components/readerControls";
// import ReaderSetting from "../../components/readerSetting";
import { Typography, Drawer, Button, Space,Tabs,List } from 'antd';
import {
  MenuOutlined,
  HomeOutlined,
  BookOutlined,
  SettingOutlined
} from '@ant-design/icons';

const { Title, Paragraph, Text, Link } = Typography;
const { TabPane } = Tabs;

//防抖
function debounce(fn,delay){
  let timer = null

  return function(...args){
    if(timer !== null)
      clearTimeout(timer)

    timer = setTimeout(()=>{
      fn.apply(this,args)
    },delay)
  }
}

//读取文件
function readFile(input) {
  const reader = new FileReader();
  const out = "";
  reader.readAsText(input); //读取文件的内容,也可以读取文件的URL
  reader.onload = function () {
    return this.result;
  };
}

let toolBarWidth = 240
let toolBarHeight = 40
//toolBarPropsReducer
const toolBarPropsReducer = (state,action) =>{
  // let {data} = action
  switch(action.type){
    case "noteBoxDisplay":
      state.noteBoxFlag = action.data
      return {...state}

    case "toolBarDisplay":
      const {selectedText,x,y,width,height} = action.data
      state.display = true
      state.left = x + width/2 - toolBarWidth/2
      state.top =  y > toolBarHeight? y - toolBarHeight -5 : y + height
      state.selectedText = selectedText

      return {...state}

    case "noteReadBoxDisplay":
      const {flag,notedText} = action.data
      state.noteReadBoxFlag = flag
      if(notedText)
        state.noteReadBoxText = notedText
      return {...state}

    case "clearToolBarDisplay":
      state.display = false
      return {...state}

    case "clearDisplay":
      state.display = false
      state.styleBtnFlag = false
      state.noteBoxFlag = false
      state.noteReadBoxFlag = false
      return {...state}

    case "styleBtnDisplay":
      state.styleBtnFlag = action.data

    default:
      return state
  }
}
const initialToolBarProps = {
  left:'',
  top:'',
  display:false,
  selectedText:'',
  noteBoxFlag:false,
  noteReadBoxFlag:false,
  noteReadBoxText:'',
  styleBtnFlag:false,
}
// export const toolBarPropsContext = React.createContext();
export const toolBarPropsContext = React.createContext();



export default function Book() {
  const params = useParams();
  const bookName = params.bookName;
  const bookListContext = useContext(BookListContext);
  const [bookDetail, setBookDetail] = useState("");

  const [theme, setTheme] = useState('normal');
  const [fontFamily, setFontFamily] = useState('SimHei');
  const [fontSize, setFontSize] = useState(24);
  const [paraStyle, setParaStyle] = useState('well');
  const defaultSetting = {
    theme:  theme ,
    setTheme:  setTheme ,
    fontFamily:  fontFamily ,
    setFontFamily:  setFontFamily ,
    fontSize:  fontSize ,
    setFontSize:  setFontSize ,
    paraStyle:  paraStyle ,
    setParaStyle: setParaStyle,
  }
  // let bookContextObj
  useEffect(() => {
    const index = bookListContext.bookListContext.findIndex((value) => {
      return value.bookName === bookName;
    });
    const input=bookListContext.bookListContext[index].file;
    const reader = new FileReader();
    reader.readAsText(input,'gb2312'); //读取文件的内容,也可以读取文件的URL
    reader.onload = function () {
      setBookDetail(this.result);
    };
    document.onselectionchange = debounce(selectionChangeEvent,300)
  },[]);

  let bookContext = useMemo(()=>{
      return bookDetail.split(/\r?\n/)
  },[bookDetail])

  const catalogue = [];
  const bookmarks = [];

  const [visible, setVisible] = useState(false);
  const [title, setTitle] = useState(false);
  const [dataSource, setDataSource] = useState(false);

  const showDrawer_1 = () => {
    setVisible(true);
    setTitle('目录');
    setDataSource(catalogue);
  };

  const showDrawer_2 = () => {
    setVisible(true);
    setTitle('书签');
    setDataSource(bookmarks);
  };

  const onClose = () => {
    setVisible(false);
  };

  //------------------------------------放置toolBar功能代码start


  const [toolBarProps, toolBarDispatch] = useReducer(toolBarPropsReducer, initialToolBarProps)
  //使用useMemo声明toolBarPropsContext的value参数，避免使用useContext组件的不必要更新
  let toolBarPropsContextValue = useMemo(()=>({toolBarProps,toolBarDispatch}),[toolBarProps])

  //鼠标按下事件，记录按下位置，并清除toolbar、notebox与notereadbox
  function mouseDownEvent(e){
    const {display, noteBoxFlag, noteReadBoxFlag} = toolBarProps
    if(display || noteBoxFlag || noteReadBoxFlag){
      toolBarDispatch({type:"clearDisplay"})
      // console.log("clearDisplay");
    }
  }

  //监听内容选区变化，显示toolBar
  function selectionChangeEvent(){
    let selection = window.getSelection()
    let range = selection.getRangeAt(0)

    if(selection.toString().trim() !== ''){
      // console.log("selectionChangeEvent");
      let x = range.getBoundingClientRect().x
      let y = range.getBoundingClientRect().y
      let width = range.getBoundingClientRect().width
      let height = range.getBoundingClientRect().height

      toolBarDispatch({type:"toolBarDisplay",data:{x,y,width,height,selectedText:selection.toString()}})
    }
  }

  //高亮
  const highLine = useCallback((selectedText)=>{
    return () =>{
      let bookDetailSplit = bookDetail.split(selectedText)
      let newBookDetail = bookDetailSplit.join(`<span class='highLineText'>${selectedText}</span>`)
      setBookDetail(newBookDetail)
    }
  },[bookDetail])

  //划线
  const underLine = useCallback((selectedText)=>{
    return () =>{
      let bookDetailSplit = bookDetail.split(selectedText)
      let newBookDetail = bookDetailSplit.join(`<span class='underLineText'>${selectedText}</span>`)
      setBookDetail(newBookDetail)
    }
  },[bookDetail])

  //添加Note
  const addNote = useCallback((selectedText)=>{
    let bookDetailSplit = bookDetail.split(selectedText)
    let newBookDetail = bookDetailSplit.join(`<span class='notedText' >${selectedText}</span>`)
    setBookDetail(newBookDetail)
  },[bookDetail])

  //删除文本样式
  const deleteStyle = useCallback((selectedText)=>{

      if(bookDetail.indexOf(`<span class='underLineText'>${selectedText}</span>`) != -1){
        let bookDetailSplit = bookDetail.split(`<span class='underLineText'>${selectedText}</span>`)
        let newBookDetail = bookDetailSplit.join(selectedText)
        setBookDetail(newBookDetail)
      }
      else{
        let bookDetailSplit = bookDetail.split(`<span class='highLineText'>${selectedText}</span>`)
        let newBookDetail = bookDetailSplit.join(selectedText)
        setBookDetail(newBookDetail)
      }
  },[bookDetail])

  //删除笔记
  const deleteNote = useCallback((selectedText)=>{
      let bookDetailSplit = bookDetail.split(`<span class='notedText' >${selectedText}</span>`)
      let newBookDetail = bookDetailSplit.join(selectedText)
      setBookDetail(newBookDetail)
      localStorage.removeItem(selectedText)
  },[bookDetail])

   //读取Note
  function readNote(notedText){
    return (e)=>{
      toolBarDispatch({type:"noteReadBoxDisplay",data:{flag:true,notedText}})
    }
  }

  //处理点击样式文本的toolBar显示
  function handleStyleText(){
    return (e)=>{
      let x = e.target.getBoundingClientRect().x
      let y = e.target.getBoundingClientRect().y
      let width = e.target.getBoundingClientRect().width
      let height = e.target.getBoundingClientRect().height

      toolBarDispatch({type:"styleBtnDisplay",data:true})
      toolBarDispatch({type:"toolBarDisplay",data:{x,y,width,height,selectedText:e.target.textContent}})
    }

  }

  //为highLineText、underLineText、notedText添加点击事件
  useEffect(()=>{
    //为高亮文本添加点击事件
    let highLineTextArr = document.querySelectorAll('.highLineText')
    for(let i=0;i<highLineTextArr.length;i++){

      if(highLineTextArr[i].onclick == null){
        highLineTextArr[i].onclick = handleStyleText(highLineTextArr[i].innerText)
      }
    }
    //为划线文本添加点击事件
    let underLineTextArr = document.querySelectorAll('.underLineText')
    for(let i=0;i<underLineTextArr.length;i++){
      if(underLineTextArr[i].onclick == null){
        underLineTextArr[i].onclick = handleStyleText(underLineTextArr[i].innerText)
      }
    }
    //为笔记文本添加点击事件
    let notedTextArr = document.querySelectorAll('.notedText')
    for(let i=0;i<notedTextArr.length;i++){
      if(notedTextArr[i].onclick == null){
        let notedText = notedTextArr[i].innerText
        notedTextArr[i].onclick = readNote(notedText)
      }
    }
  })

  //------------------------------------放置toolBar功能代码end

  return (
    <toolBarPropsContext.Provider value={toolBarPropsContextValue} >
    <div className={theme+" readerBackground"}>
      <div className='icon'>
      &nbsp;
        {/* <Button icon={<HomeOutlined />} onClick={()=>this.props.history.go(-1)}></Button>&nbsp; */}
        <Button icon={<MenuOutlined />} shape='circle' size='large' onClick={showDrawer_1} value='5461'></Button>&nbsp;
        <Button icon={<BookOutlined />} shape='circle' size='large' onClick={showDrawer_2} id='2'></Button>&nbsp;
        {/* <Button icon={<SettingOutlined />} onClick={showDrawer_2} id='2'></Button> */}
        <Drawer title={title} placement="left" onClose={onClose} visible={visible} >
          <List
            bordered
            dataSource={dataSource}
            renderItem={item => <List.Item>{item}</List.Item>}
          />
        </Drawer>
      </div>


      <div className={theme + ' readerBody book ' + paraStyle} >
        <Typography className={theme + ' ' + fontFamily + 'bookDetailBox' }  style={{fontSize:fontSize,lineHeight:'36px'}} onMouseDown={mouseDownEvent}>
        {/* <Typography className={theme + ' ' + fontFamily + 'bookDetailBox' }  style={{fontSize:fontSize,lineHeight:'36px'}} onMouseUp={mouseUpEvent} onMouseDown={mouseDownEvent}> */}
          <Title>{bookName}</Title>
          {bookContext.map((data,index)=>{
            if(data.search(/^(?=.*第)(?=.*章)/)!=-1){
              catalogue.push(data)

              return <Title level={2} key={`paragraph${index}`}>{data}</Title>
            }
            return (
                  <p key={`paragraph${index}`} dangerouslySetInnerHTML={{__html:data}} className='bookDetail' style={{marginBottom:'36px'}} ></p>
            )
          })}

          <ToolBar highLine={highLine} underLine={underLine} deleteStyle={deleteStyle}/>

        </Typography>

        <NoteBox addNote={addNote}/>
        <NoteReadBox  deleteNote={deleteNote}/>

        <div className='progress'>22.1%</div>
      </div>


      <ReaderControls {...defaultSetting} />
    </div>
    </toolBarPropsContext.Provider>
  );
}
